Skip to main content

Classic Command API

A command in Imperat is represented internally by the class dev.velix.imperat.command.Command which holds every command's data and needed usages.

Sub-commands at the other hand, are themselves Command, simply there's no class called Subcommand or something like that, Subcommands are treated as commands and can be easily combined together in the form of a chain by merging the main-usage of a command to the subcommand's usage.

Moreover, A Command is also treated as a CommandParameter that can be added to a CommandUsage.

We will be learning every possible way of modifying the Command object you create (Classic) But first let's get to know the Mutable components of a command.

Every single Command object has the following mutable components :-

  • Aliases (other names could be used for a command)
  • Permission
  • Description
  • Default-usage (/<command> without any arguments )
  • Usages
  • Processors

Example

Here we will be creating our command builder instance :

var command = Command.<YourPlatformSource>createCommand("example");

Adding aliases

We want our command to have more than one identifiable name.

command.aliases("example2", "example3", "example4", "example5");

Setting Command Permission

We can easily define a permission for our command as the example below:

command.permission("command.example.permission");

Setting Command Description

Same as before but using different method

command.description("This is an example command !");

Setting default-usage-executor

Now we want to define what happens when the command sender executes the command in the command-line without any arguments.

command.defaultExecution((source, context)-> {  
source.reply("This is just an example with no arguments entered");
});

Adding your Processors

WARNING

If you don't know what is a CommandProcessor, please check out Command Processors

It's easy to add post and pre processors as example below

command.preprocessor(new YourCommandPreProcessor())
.postProcessor(new YourCommandPostProcessor());

Adding Command Usages

A normal usage usually has no special CommandParameter types(such as Command), which can be added easily as below:

command.usage(CommandUsage.<YourPlatformSource>builder()  
.parameters(
CommandParameter.requiredInt("firstArg")
).execute((source, context) -> {
Integer firstArg = context.getArgument("firstArg");
source.reply("Entered required number= " + firstArg);
})
);

However, what if you wanted to add subcommands, you cant add a subcommand directly through creating it manually(it's possible) as it will require a lot of processing and will be ugly looking.

Therefore, The Command object is made with such automated processing and chaining of subcommands through the method Command#addSubCommandUsage as the example below :-

command.subCommand("sub1",
CommandUsage.<YourPlatformSource>builder()
.parameters(
CommandParameter.optional("value", Double.class,OptionalValueSupplier.of(-1D))
).execute((source, context)-> {
//you can get previously used arguments from the main command usage
Integer firstArg = context.getArgument("firstArg");
source.reply("Entered firstArg= " + firstArg);
Double value = context.getArgument("value");
assert value != null; //optional arg cant be null, it has a default value supplier
source.reply("Double value entered= " + value);
})
);

After the example above, a new usage internally will be created and shall look like /example <firstArg> sub1 [value].

Setting processors

It's easy just follow your instinct and you will find the following example useful.

command.preProcessor(new MyPreProcessor()).postProcessor(new MyPostProcessor());

Extras

There are multiple extra options to consider when adding a subcommand to a command :-

  • aliases

  • attachDirectly(false by default) -> Whether the subcommand usage will be merged with the command's default usage (not main usage), so if true it will be /example sub1 [value]

  • You can also declare a usage to be executed asynchronously by using the method CommandUsage.Builder#coordinator which takes a CommandCoordinator instance. as shown below:

usageBuilder.coordinator(CommandCoordinator.async());
  • You can add a cooldown per command usage as the example below:
usageBuilder.cooldown(1, TimeUnit.SECONDS); //cooldown of 1 second

CRITICAL
  • DO NOT USE CommandUsage.Builder#build to add an instance of a usage, it might break some internals, please return the builders.
  • NEVER CALL Command#setPosition for any reason (even if you were Joshua Bloch)
  • If you don't know what is an ambiguity between 2 different usages, please check out UsageVerifier